#include "GraphicsViewArea.h"
#include "ui_GraphicsViewArea.h"
#include <QVBoxLayout>
#include <QTransform>
#include <QResizeEvent>
#include <QRegExp>
#include <QRegExpValidator>
#include <QGraphicsSceneMouseEvent>
#include <QEvent>
#include <QColor>
#include <QGridLayout>
#include <QScrollBar>
#include <cmath>
#include "UnitConversionDialog.h"
#include <QDebug>
#include <QThread>
GraphicsViewArea::GraphicsViewArea(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::GraphicsViewArea),
    m_lengthRatio(1.0),
    m_timeRatio(1.0),
    m_wavelengthRatio(1.0),
    m_lengthUnit("mm"),
    m_timeUnit("us"),
    m_wavelengthUnit("nm"),
    m_currentImageGuid("")
{
    ui->setupUi(this);

    m_scene = new QGraphicsScene(this);
    ui->imagesDisplayGraphicsView->setScene(m_scene);
    ui->imagesDisplayGraphicsView->setRenderHint(QPainter::Antialiasing);
    ui->imagesDisplayGraphicsView->setRenderHint(QPainter::SmoothPixmapTransform);
    // 默认禁用拖动模式，只有当点击拖动按钮时才启用
    ui->imagesDisplayGraphicsView->setDragMode(QGraphicsView::NoDrag);
    ui->imagesDisplayGraphicsView->setAlignment(Qt::AlignCenter);
    ui->imagesDisplayGraphicsView->installEventFilter(this);
    ui->imagesDisplayGraphicsView->viewport()->installEventFilter(this);
    m_scene->installEventFilter(this);
    //设置鼠标跟踪
    ui->imagesDisplayGraphicsView->setMouseTracking(true);

    // 将movePushButton设置为可检查状态
    ui->movePushButton->setCheckable(true);

    m_axisItem = new CoordinateAxisItem();
    m_scene->addItem(m_axisItem);
    m_imageItem = nullptr;
    m_scale = 1.0;
    m_isCalibrating = false;
    m_xCalibrationLine = nullptr;
    m_yCalibrationLine = nullptr;
    m_isDraggingXLine = false;
    m_isDraggingYLine = false;
    m_dragStartPos = QPointF();

    // 显示图形视图
    ui->imagesDisplayGraphicsView->show();

    // 连接信号和槽
    connect(ui->imagesDisplayGraphicsView->horizontalScrollBar(), &QScrollBar::valueChanged, this, &GraphicsViewArea::onViewChanged);
    connect(ui->imagesDisplayGraphicsView->verticalScrollBar(), &QScrollBar::valueChanged, this, &GraphicsViewArea::onViewChanged);

    connect(ui->xCoordinateLineEdit, &QLineEdit::editingFinished, this, &GraphicsViewArea::on_xCoordinateLineEdit_editingFinished);
    connect(ui->yCoordinateLineEdit, &QLineEdit::editingFinished, this, &GraphicsViewArea::on_yCoordinateLineEdit_editingFinished);
    connect(ui->xAxisUnitComboBox, &QComboBox::currentTextChanged, this, &GraphicsViewArea::onXAxisUnitChanged);
    connect(ui->yAxisUnitComboBox, &QComboBox::currentTextChanged, this, &GraphicsViewArea::onYAxisUnitChanged);

    // 设置默认单位
    ui->xAxisUnitComboBox->setCurrentText("像素");
    ui->yAxisUnitComboBox->setCurrentText("像素");

    // 初始调用一次坐标轴设置
    onXAxisUnitChanged("像素");
    onYAxisUnitChanged("像素");

    // 初始化缩放比例显示
    ui->scalingLineEdit->setText("100%");

    // 连接scalingLineEdit的信号
    connect(ui->scalingLineEdit, &QLineEdit::editingFinished, this, &GraphicsViewArea::on_scalingLineEdit_editingFinished);
}

GraphicsViewArea::~GraphicsViewArea()
{
    delete ui;
    // 清理标定线条资源
    if (m_xCalibrationLine) {
        delete m_xCalibrationLine;
        m_xCalibrationLine = nullptr;
    }
    if (m_yCalibrationLine) {
        delete m_yCalibrationLine;
        m_yCalibrationLine = nullptr;
    }
}

void GraphicsViewArea::setImage(const QPixmap &pixmap)
{
    if(m_imageItem)
    {
        m_imageItem ->setPixmap(pixmap);
        return;
    }
    // 重新确认鼠标跟踪设置
    ui->imagesDisplayGraphicsView->setMouseTracking(true);
    ui->imagesDisplayGraphicsView->viewport()->setMouseTracking(true);
    setMouseTracking(true);
    
    // 保存当前缩放比例和视图位置
    qreal savedScale = m_scale;
    int hScrollValue = ui->imagesDisplayGraphicsView->horizontalScrollBar()->value();
    int vScrollValue = ui->imagesDisplayGraphicsView->verticalScrollBar()->value();
    
    // 如果已有图像项，先移除
    if (m_imageItem) {
        m_scene->removeItem(m_imageItem);
        delete m_imageItem;
        m_imageItem = nullptr;
    }

    // 临时保存标定线条的可见状态
    bool xLineVisible = false;
    bool yLineVisible = false;
    if (m_xCalibrationLine) {
        xLineVisible = m_xCalibrationLine->isVisible();
    }
    if (m_yCalibrationLine) {
        yLineVisible = m_yCalibrationLine->isVisible();
    }

    // 如果传入的图像为空，直接返回
    if (pixmap.isNull()) {
        return;
    }

    // 创建新的图像项
    m_imageItem = new QGraphicsPixmapItem(pixmap);
    m_scene->addItem(m_imageItem);

    // 将图像放置在画布最左上角，但避开坐标轴占用的空间（在paint方法中定义了xAxisOffset=30和yAxisOffset=30）
    // 这样可以确保图像不会被坐标轴和刻度文字遮挡
    QSize axisOffset=m_axisItem->getFixedOffset();
    m_imageItem->setPos(axisOffset.width(),axisOffset.height());

    // 设置图像项不接收任何鼠标事件
    m_imageItem->setAcceptHoverEvents(false);
    m_imageItem->setAcceptedMouseButtons(Qt::NoButton);
    m_imageItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
    m_imageItem->setFlag(QGraphicsItem::ItemIsMovable, false);
    m_imageItem->setFlag(QGraphicsItem::ItemIgnoresTransformations, false);
    // 设置图像项的zValue为中间值
    m_imageItem->setZValue(0);

    // 获取图像的大小
    QSize imageSize = pixmap.size();

    // 保存原始图像大小，用于计算刻度间隔
    m_originalImageSize = imageSize;

    // 设置场景范围，使用图像大小加上坐标轴偏移量
    // 这样可以确保即使图像超出视图范围，整个图像区域也能在场景中显示
    m_scene->setSceneRect(0, 0, imageSize.width() + 50, imageSize.height() + 50);

    // 调整坐标轴范围，使其与整个图像大小一致
    // 这样可以确保坐标轴显示整个图像的刻度，而不仅仅是可视区域的刻度
    QSize viewportSize = ui->imagesDisplayGraphicsView->viewport()->size();
    QPoint offset(ui->imagesDisplayGraphicsView->horizontalScrollBar()->value(),
                  ui->imagesDisplayGraphicsView->verticalScrollBar()->value());
    m_axisItem->setAxisRange(m_scale, imageSize, viewportSize, offset);

    // 确保坐标轴项不接收鼠标事件
    m_axisItem->setAcceptHoverEvents(false);
    m_axisItem->setAcceptedMouseButtons(Qt::NoButton);
    m_axisItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
    m_axisItem->setFlag(QGraphicsItem::ItemIsMovable, false);
    m_axisItem->setZValue(1000);

    // 设置缩放比例为之前保存的值，而不是重置为1.0
    if (m_imageItem) {
        QTransform transform;
        transform.scale(savedScale, savedScale);
        m_imageItem->setTransform(transform);
        m_scale = savedScale;
    }
    // 调整刻度间隔
    adjustTickInterval();

    // 不要重置变换，而是保持之前的缩放状态
    // ui->imagesDisplayGraphicsView->resetTransform();
    // 不要使用fitInView，这样当图像超出视图时会显示滚动条
    ui->imagesDisplayGraphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    ui->imagesDisplayGraphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    
    // 恢复视图位置
    ui->imagesDisplayGraphicsView->horizontalScrollBar()->setValue(hScrollValue);
    ui->imagesDisplayGraphicsView->verticalScrollBar()->setValue(vScrollValue);

    // 更新缩放比例显示
    ui->scalingLineEdit->setText(QString("%1%2").arg(m_scale * 100).arg("%"));

    // 恢复标定线条的可见状态
    if (m_xCalibrationLine) {
        m_xCalibrationLine->setVisible(xLineVisible);
    }
    if (m_yCalibrationLine) {
        m_yCalibrationLine->setVisible(yLineVisible);
    }
}


void GraphicsViewArea::updateImage(const QPixmap &pixmap)
{
    if(!m_imageItem)
    {
        setImage(pixmap);
        return;
    }
    m_imageItem->setPixmap(pixmap);
    //    m_imageItem->update();
}

QSize GraphicsViewArea::getImageOffset() const
{
    return QSize(m_imageItem->pos().x(),m_imageItem->pos().y());
}


void GraphicsViewArea::resizeEvent(QResizeEvent *event)
{
    // 调用父类的resizeEvent
    QWidget::resizeEvent(event);

    // 获取视图的新大小
    QSize viewSize = ui->imagesDisplayGraphicsView->viewport()->size();

    if (!m_imageItem) {
        // 当没有图像时，将场景范围设置为视图大小
        m_scene->setSceneRect(0, 0, viewSize.width(), viewSize.height());
    } else {
        // 根据用户建议：当有图像时，也应该动态调整场景范围，确保场景范围足够大
        // 获取缩放后的图像尺寸
        QSize scaledImageSize = m_originalImageSize * m_scale;

        // 计算新的场景尺寸（取图像缩放后尺寸和视图尺寸的较大值）
        int newWidth = qMax(scaledImageSize.width() + 50, viewSize.width());
        int newHeight = qMax(scaledImageSize.height() + 50, viewSize.height());

        // 更新场景范围
        m_scene->setSceneRect(0, 0, newWidth, newHeight);
    }

    // 调整坐标轴范围，使其与场景大小一致
    QPoint offset(ui->imagesDisplayGraphicsView->horizontalScrollBar()->value(),
                  ui->imagesDisplayGraphicsView->verticalScrollBar()->value());
    m_axisItem->setAxisRange(m_scale, m_originalImageSize, viewSize, offset);

    // 调整刻度间隔
    adjustTickInterval();
}

bool GraphicsViewArea::eventFilter(QObject *watched, QEvent *event)
{
    // 在方法顶部定义变量，确保它们在整个方法中都可用
    QPointF scenePos;
    bool hasValidScenePos = false;
    bool handled = false;




    // 确保事件过滤器能够捕获所有事件，包括视图、视口和场景的事件
    if (watched == ui->imagesDisplayGraphicsView || watched == ui->imagesDisplayGraphicsView->viewport() || watched == m_scene) {

        // 优先处理滚轮事件，无论鼠标悬停在哪个组件上
        if (event->type() == QEvent::Wheel && m_imageItem) {
            QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
            // 如果按下Ctrl键，则执行缩放操作
            // 根据滚轮方向调整缩放比例
            qreal factor = 1.1; // 缩放因子
            if (wheelEvent->delta() < 0) {
                factor = 1.0 / factor;
            }

            // 获取当前图像项的变换
            QTransform transform = m_imageItem->transform();

            // 保存当前缩放比例
            qreal currentItemScale = transform.m11();

            // 计算新的缩放比例
            qreal newScale = currentItemScale * factor;

            // 限制缩放范围
            const qreal minScale = 0.1;  // 最小缩放比例
            const qreal maxScale = 10.0; // 最大缩放比例
            if (newScale < minScale) newScale = minScale;
            if (newScale > maxScale) newScale = maxScale;

            setScale(newScale);

            // 接受事件，阻止其传递给滚动条
            wheelEvent->accept();
            return true;
        }

        // 获取场景坐标，无论事件类型如何
        if (watched == ui->imagesDisplayGraphicsView || watched == ui->imagesDisplayGraphicsView->viewport()) {
            if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseMove || event->type() == QEvent::MouseButtonRelease) {
                QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
                scenePos = ui->imagesDisplayGraphicsView->mapToScene(mouseEvent->pos());
                hasValidScenePos = true;
            }
        } else if (watched == m_scene) {
            if (event->type() == QEvent::GraphicsSceneMousePress ||
                event->type() == QEvent::GraphicsSceneMouseMove ||
                event->type() == QEvent::GraphicsSceneMouseRelease) {
                QGraphicsSceneMouseEvent *sceneMouseEvent = static_cast<QGraphicsSceneMouseEvent*>(event);
                scenePos = sceneMouseEvent->scenePos();
                hasValidScenePos = true;
            }
        }

        // 处理鼠标移动事件 - 无论标定是否激活都更新位置显示
        if (event->type() == QEvent::MouseMove || event->type() == QEvent::GraphicsSceneMouseMove) {
            if (hasValidScenePos) {
                // 获取鼠标在场景中的位置
                qreal xPos = scenePos.x();
                qreal yPos = scenePos.y();

                // 如果图像存在，计算相对于图像起始点的位置，并考虑单位转换比例
                if (m_imageItem) {
                    // 获取图像项在场景中的位置
                    QPointF imagePos = m_imageItem->pos();
                    
                    // 计算并存储相对于图像起始点的位置（以像素为单位）
                    m_mouseRelX = xPos - imagePos.x();
                    m_mouseRelY = yPos - imagePos.y();
                    
                    // 更新鼠标位置显示
                    updateMousePositionDisplay();
                } else {
                    // 简化逻辑：只要鼠标在视图上就更新位置显示，不严格限制在场景范围内
                    ui->label_MouseX->setText(QString::number(qRound(xPos)));
                    ui->label_MouseY->setText(QString::number(qRound(yPos)));
                }
            }
        }

        // 只有在标定功能激活时才处理标定相关的事件
        if (m_isCalibrating && hasValidScenePos && m_xCalibrationLine && m_yCalibrationLine) {
            switch (event->type()) {
            case QEvent::MouseButtonPress:
            case QEvent::GraphicsSceneMousePress: {
                // 优化：直接使用itemAt检查是否点击了标定线，避免获取大量项目
                QGraphicsItem *item = m_scene->itemAt(scenePos, ui->imagesDisplayGraphicsView->transform());

                if (item == m_xCalibrationLine) {
                    m_isDraggingXLine = true;
                    m_dragStartPos = scenePos;
                    ui->imagesDisplayGraphicsView->setCursor(Qt::SizeHorCursor);
                    handled = true;
                } else if (item == m_yCalibrationLine) {
                    m_isDraggingYLine = true;
                    m_dragStartPos = scenePos;
                    ui->imagesDisplayGraphicsView->setCursor(Qt::SizeVerCursor);
                    handled = true;
                }
                break;
            }
            case QEvent::MouseMove:
            case QEvent::GraphicsSceneMouseMove: {
                if (m_isDraggingXLine) {
                    // 获取场景范围
                    QRectF sceneRect = m_scene->sceneRect();

                    // 计算新的X坐标
                    qreal newX = scenePos.x();
                    // 限制在场景范围内
                    newX = qMax(sceneRect.left(), qMin(sceneRect.right(), newX));

                    // 获取图像项在场景中的位置
                    QPointF imagePos = m_imageItem->pos();
                    
                    // 计算相对于图像起始点的位置
                    qreal relX = newX - imagePos.x();
                    
                    // 获取X轴的当前单位和转换比例
                    CoordinateAxisItem::AxisUnit xUnit = m_axisItem->xAxisUnit();
                    double xRatio = 1.0;
                    
                    // 根据单位类型选择相应的转换比例
                    if (xUnit == CoordinateAxisItem::Length) {
                        xRatio = m_lengthRatio;
                    } else if (xUnit == CoordinateAxisItem::Time) {
                        xRatio = m_timeRatio;
                    } else if (xUnit == CoordinateAxisItem::Wavelength) {
                        xRatio = m_wavelengthRatio;
                    }
                    
                    // 应用单位转换比例和缩放比例，将显示坐标转换回像素坐标
                    qreal pixelX = newX;
                    
                    // 更新X轴标定线位置
                    m_xCalibrationLine->setLine(pixelX, sceneRect.top(), pixelX, sceneRect.bottom());

                    // 更新输入框显示（以实际单位显示，考虑缩放比例）
                    qreal displayX = relX * xRatio / m_scale;
                    ui->xCoordinateLineEdit->setText(QString::number(displayX, 'f', 2));

                    m_dragStartPos = scenePos;
                    handled = true;
                } else if (m_isDraggingYLine) {
                    // 获取场景范围
                    QRectF sceneRect = m_scene->sceneRect();

                    // 计算新的Y坐标
                    qreal newY = scenePos.y();
                    // 限制在场景范围内
                    newY = qMax(sceneRect.top(), qMin(sceneRect.bottom(), newY));

                    // 获取图像项在场景中的位置
                    QPointF imagePos = m_imageItem->pos();
                    
                    // 计算相对于图像起始点的位置
                    qreal relY = newY - imagePos.y();
                    
                    // 获取Y轴的当前单位和转换比例
                    CoordinateAxisItem::AxisUnit yUnit = m_axisItem->yAxisUnit();
                    double yRatio = 1.0;
                    
                    // 根据单位类型选择相应的转换比例
                    if (yUnit == CoordinateAxisItem::Length) {
                        yRatio = m_lengthRatio;
                    } else if (yUnit == CoordinateAxisItem::Time) {
                        yRatio = m_timeRatio;
                    } else if (yUnit == CoordinateAxisItem::Wavelength) {
                        yRatio = m_wavelengthRatio;
                    }
                    
                    // 应用单位转换比例和缩放比例，将显示坐标转换回像素坐标
                    qreal pixelY = newY;
                    
                    // 更新Y轴标定线位置
                    m_yCalibrationLine->setLine(sceneRect.left(), pixelY, sceneRect.right(), pixelY);

                    // 更新输入框显示（以实际单位显示，考虑缩放比例）
                    qreal displayY = relY * yRatio / m_scale;
                    ui->yCoordinateLineEdit->setText(QString::number(displayY, 'f', 2));

                    m_dragStartPos = scenePos;
                    handled = true;
                } else {
                    // 优化：只有在未拖动时才更新光标
                    QGraphicsItem *item = m_scene->itemAt(scenePos, ui->imagesDisplayGraphicsView->transform());

                    if (item == m_xCalibrationLine) {
                        ui->imagesDisplayGraphicsView->setCursor(Qt::SizeHorCursor);
                    } else if (item == m_yCalibrationLine) {
                        ui->imagesDisplayGraphicsView->setCursor(Qt::SizeVerCursor);
                    } else {
                        ui->imagesDisplayGraphicsView->setCursor(Qt::ArrowCursor);
                    }
                }
                break;
            }
            case QEvent::MouseButtonRelease:
            case QEvent::GraphicsSceneMouseRelease: {
                if (m_isDraggingXLine || m_isDraggingYLine) {
                    m_isDraggingXLine = false;
                    m_isDraggingYLine = false;
                    ui->imagesDisplayGraphicsView->setCursor(Qt::ArrowCursor);
                    handled = true;
                }
                break;
            }
            default:
                break;
            }
        } else {
            // 标定功能未激活时，确保光标为默认状态
            if (event->type() == QEvent::MouseMove || event->type() == QEvent::GraphicsSceneMouseMove) {
                ui->imagesDisplayGraphicsView->setCursor(Qt::ArrowCursor);
            }
        }
    }

    // 优化事件过滤器返回逻辑，确保所有功能正常工作

    // 如果事件已被处理，返回true
    if (handled) {
        return true;
    }

    // 非标定模式下，确保视图的拖动功能能正常工作
    // 对于视口和视图的鼠标事件，不调用父类事件过滤器，让Qt默认处理
    if (watched == ui->imagesDisplayGraphicsView || watched == ui->imagesDisplayGraphicsView->viewport()) {
        return false; // 让Qt默认处理视口和视图的事件，确保拖动功能正常
    }

    // 对于场景的事件，调用父类的事件过滤器
    return QWidget::eventFilter(watched, event);
}

void GraphicsViewArea::onViewChanged()
{
    // 当视图变换时，调整刻度间隔
    adjustTickInterval();
}

void GraphicsViewArea::adjustTickInterval()
{
    // 调用唯一的坐标轴更新接口，传递缩放比例、图像大小和可视区域大小以及偏移位置
    QSize viewSize = ui->imagesDisplayGraphicsView->viewport()->size();
    QPoint offset(ui->imagesDisplayGraphicsView->horizontalScrollBar()->value(),
                  ui->imagesDisplayGraphicsView->verticalScrollBar()->value());
    m_axisItem->setAxisRange(m_scale, m_originalImageSize, viewSize, offset);

    // 更新缩放比例显示
    ui->scalingLineEdit->setText(QString::number(static_cast<int>(m_scale * 100)) + "%");
}

qreal GraphicsViewArea::getCurrentScale() const
{
    return m_scale;
}

void GraphicsViewArea::setScale(qreal scale)
{
    if (scale <= 0 || !m_imageItem) {
        return;
    }

    // 计算缩放比例的变化
    qreal scaleFactor = scale / m_scale;

    // 应用缩放变换
    QTransform transform = m_imageItem->transform();
    transform.scale(scaleFactor, scaleFactor);
    m_imageItem->setTransform(transform);

    // 更新缩放比例
    m_scale = scale;

    // 更新缩放比例显示
    ui->scalingLineEdit->setText(QString::number(static_cast<int>(m_scale * 100)) + "%");

    // 根据用户建议：更新场景范围，确保场景范围始终至少与视图大小或缩放后的图像大小一样大
    // 获取缩放后的图像尺寸
    QSize scaledImageSize = m_originalImageSize * m_scale;
    // 获取视图大小
    QSize viewSize = ui->imagesDisplayGraphicsView->viewport()->size();

    // 计算新的场景尺寸（取图像缩放后尺寸和视图尺寸的较大值）
    int newWidth = qMax(scaledImageSize.width() + 50, viewSize.width());
    int newHeight = qMax(scaledImageSize.height() + 50, viewSize.height());

    // 更新场景范围
    m_scene->setSceneRect(0, 0, newWidth, newHeight);

    // 调整刻度间隔
    adjustTickInterval();
    
    //刷新标定线
    refreshCalibrationLines();

    // 发出缩放比例变化信号
    emit scaleChanged(m_currentImageGuid, m_scale);
}

QGraphicsScene* GraphicsViewArea::getScene() const
{
    return m_scene;
}

void GraphicsViewArea::updateConversionRatios(double lengthRatio, double timeRatio, double wavelengthRatio, const QString &lengthUnit, const QString &timeUnit, const QString &wavelengthUnit)
{
    m_lengthRatio = lengthRatio;
    m_timeRatio = timeRatio;
    m_wavelengthRatio = wavelengthRatio;
    
    // 更新单位信息（如果提供了新值）
    if (!lengthUnit.isEmpty()) {
        m_lengthUnit = lengthUnit;
    }
    if (!timeUnit.isEmpty()) {
        m_timeUnit = timeUnit;
    }
    if (!wavelengthUnit.isEmpty()) {
        m_wavelengthUnit = wavelengthUnit;
    }

    // 调整坐标轴显示
    adjustTickInterval();
    
    // 发出单位转换变化信号
    emit conversionInfoChanged(m_currentImageGuid, m_lengthRatio, m_timeRatio, m_wavelengthRatio,
                             m_lengthUnit, m_timeUnit, m_wavelengthUnit, 
                             ui->xAxisUnitComboBox->currentIndex(), ui->yAxisUnitComboBox->currentIndex());
}

void GraphicsViewArea::setImageGuid(const QString &imageGuid)
{
    m_currentImageGuid = imageGuid;
}

QString GraphicsViewArea::getImageGuid() const
{
    return m_currentImageGuid;
}

void GraphicsViewArea::on_amplifyPushButton_clicked()
{
    if (!m_imageItem) {
        return;
    }

    // 计算新的缩放比例
    qreal newScale = m_scale * 1.1;

    // 设置新的缩放比例
    setScale(newScale);
}

void GraphicsViewArea::on_reducePushButton_clicked()
{
    if (!m_imageItem) {
        return;
    }

    // 计算新的缩放比例
    qreal newScale = m_scale * 0.9;

    // 设置新的缩放比例
    setScale(newScale);
}

void GraphicsViewArea::on_scalingLineEdit_editingFinished()
{
    if (!m_imageItem) {
        return;
    }

    // 获取输入的缩放比例
    QString text = ui->scalingLineEdit->text();
    text.remove("%"); // 移除百分号
    bool ok;
    int scalePercent = text.toInt(&ok);
    if (!ok) {
        // 输入无效，恢复原来的显示
        ui->scalingLineEdit->setText(QString::number(static_cast<int>(m_scale * 100)) + "%");
        return;
    }

    // 限制缩放范围
    if (scalePercent < 10) {
        scalePercent = 10;
    }
    if (scalePercent > 500) {
        scalePercent = 500;
    }

    // 计算新的缩放比例
    qreal newScale = scalePercent / 100.0;

    // 设置新的缩放比例
    setScale(newScale);
}

void GraphicsViewArea::on_positPushButton_clicked()
{
    // 切换标定功能激活状态
    m_isCalibrating = !m_isCalibrating;

    if (m_isCalibrating) {
        // 激活状态：绘制标定线
        ui->positPushButton->setText("取消标记");

        // 刷新标定线
        refreshCalibrationLines();
    } else {
        // 非激活状态：隐藏标定线
        ui->positPushButton->setText("坐标标记");

        if (m_xCalibrationLine) {
            m_scene->removeItem(m_xCalibrationLine);
            delete m_xCalibrationLine;
            m_xCalibrationLine = nullptr;
        }

        if (m_yCalibrationLine) {
            m_scene->removeItem(m_yCalibrationLine);
            delete m_yCalibrationLine;
            m_yCalibrationLine = nullptr;
        }
    }
}

void GraphicsViewArea::refreshCalibrationLines()
{
    if (!m_imageItem) {
        return; // 如果没有图像，不刷新标定线
    }

    // 获取输入的X坐标和Y坐标
    QString xText = ui->xCoordinateLineEdit->text();
    QString yText = ui->yCoordinateLineEdit->text();

    bool xOk, yOk;
    double xCoord = xText.toDouble(&xOk);
    double yCoord = yText.toDouble(&yOk);

    // 获取图像项在场景中的位置
    QPointF imagePos = m_imageItem->pos();

    // 获取X轴和Y轴的当前单位和转换比例
    CoordinateAxisItem::AxisUnit xUnit = m_axisItem->xAxisUnit();
    CoordinateAxisItem::AxisUnit yUnit = m_axisItem->yAxisUnit();
    
    double xRatio = 1.0;
    double yRatio = 1.0;
    
    // 根据单位类型选择相应的转换比例
    if (xUnit == CoordinateAxisItem::Length) {
        xRatio = m_lengthRatio;
    } else if (xUnit == CoordinateAxisItem::Time) {
        xRatio = m_timeRatio;
    } else if (xUnit == CoordinateAxisItem::Wavelength) {
        xRatio = m_wavelengthRatio;
    }
    
    if (yUnit == CoordinateAxisItem::Length) {
        yRatio = m_lengthRatio;
    } else if (yUnit == CoordinateAxisItem::Time) {
        yRatio = m_timeRatio;
    } else if (yUnit == CoordinateAxisItem::Wavelength) {
        yRatio = m_wavelengthRatio;
    }

    // 将用户输入的单位坐标转换为场景中的像素坐标，并考虑缩放比例
    qreal pixelX = xCoord / xRatio * m_scale + imagePos.x();
    qreal pixelY = yCoord / yRatio * m_scale + imagePos.y();

    if (!xOk || !yOk) {
        // 输入无效，使用默认坐标（图像起始点0,0）
        pixelX = imagePos.x();
        pixelY = imagePos.y();
        ui->xCoordinateLineEdit->setText("0.00");
        ui->yCoordinateLineEdit->setText("0.00");
    }

    // 获取场景范围
    QRectF sceneRect = m_scene->sceneRect();

    // 移除之前的标定线（如果存在）
    if (m_xCalibrationLine) {
        m_scene->removeItem(m_xCalibrationLine);
        delete m_xCalibrationLine;
        m_xCalibrationLine = nullptr;
    }

    if (m_yCalibrationLine) {
        m_scene->removeItem(m_yCalibrationLine);
        delete m_yCalibrationLine;
        m_yCalibrationLine = nullptr;
    }

    // 创建新的标定线
    QPen calibrationPen(Qt::red);
    calibrationPen.setWidth(2);

    // 绘制X轴标定线
    m_xCalibrationLine = new QGraphicsLineItem(QLineF(pixelX, sceneRect.top(), pixelX, sceneRect.bottom()));
    m_xCalibrationLine->setPen(calibrationPen);
    m_xCalibrationLine->setFlag(QGraphicsItem::ItemIsMovable, false);
    m_xCalibrationLine->setFlag(QGraphicsItem::ItemIsSelectable, false);
    m_xCalibrationLine->setFlag(QGraphicsItem::ItemSendsScenePositionChanges, true);
    // 允许标定线接收鼠标事件
    m_xCalibrationLine->setAcceptHoverEvents(true);
    // 显式设置标定线接收所有鼠标按钮事件
    m_xCalibrationLine->setAcceptedMouseButtons(Qt::AllButtons);
    m_xCalibrationLine->setAcceptDrops(false);
    m_xCalibrationLine->setAcceptTouchEvents(false);
    m_scene->addItem(m_xCalibrationLine);

    // 绘制Y轴标定线
    m_yCalibrationLine = new QGraphicsLineItem(QLineF(sceneRect.left(), pixelY, sceneRect.right(), pixelY));
    m_yCalibrationLine->setPen(calibrationPen);
    m_yCalibrationLine->setFlag(QGraphicsItem::ItemIsMovable, false);
    m_yCalibrationLine->setFlag(QGraphicsItem::ItemIsSelectable, false);
    m_yCalibrationLine->setFlag(QGraphicsItem::ItemSendsScenePositionChanges, true);
    // 允许标定线接收鼠标事件
    m_yCalibrationLine->setAcceptHoverEvents(true);
    // 显式设置标定线接收所有鼠标按钮事件
    m_yCalibrationLine->setAcceptedMouseButtons(Qt::AllButtons);
    m_yCalibrationLine->setAcceptDrops(false);
    m_yCalibrationLine->setAcceptTouchEvents(false);
    m_scene->addItem(m_yCalibrationLine);

    // 将标定线放在所有图层最上面，确保能够被点击到
    m_xCalibrationLine->setZValue(1);
    m_yCalibrationLine->setZValue(1);
}

void GraphicsViewArea::on_xCoordinateLineEdit_editingFinished()
{
    // 只有在标定功能激活时才处理
    if (m_isCalibrating) {
        refreshCalibrationLines();
    }
}

void GraphicsViewArea::on_yCoordinateLineEdit_editingFinished()
{
    // 只有在标定功能激活时才处理
    if (m_isCalibrating) {
        refreshCalibrationLines();
    }
}

void GraphicsViewArea::onXAxisUnitChanged(const QString &unit)
{
    if (m_axisItem) {
        // 将字符串转换为AxisUnit枚举类型
        CoordinateAxisItem::AxisUnit axisUnit = CoordinateAxisItem::Pixel;
        double ratio = 1.0;
        QString unitString = "px";

        if (unit == "像素") {
            axisUnit = CoordinateAxisItem::Pixel;
            ratio = 1.0;
            unitString = "px";
        } else if (unit == "长度") {
            axisUnit = CoordinateAxisItem::Length;
            ratio = m_lengthRatio;
            // 使用动态存储的长度单位
            unitString = m_lengthUnit;
        } else if (unit == "时间") {
            axisUnit = CoordinateAxisItem::Time;
            ratio = m_timeRatio;
            // 使用动态存储的时间单位
            unitString = m_timeUnit;
        } else if (unit == "波长") {
            axisUnit = CoordinateAxisItem::Wavelength;
            ratio = m_wavelengthRatio;
            // 使用动态存储的波长单位
            unitString = m_wavelengthUnit;
        }

        // 设置X轴单位、转换比例和具体单位字符串
        m_axisItem->setXAxisProperties(axisUnit, unitString, ratio);
        
        // 更新鼠标位置显示
        updateMousePositionDisplay();
        
        // 如果标定功能激活，根据标定线相对图像的偏移更新显示值
        if (m_isCalibrating) {
            updateCalibrationValues();
        }
        
        // 发出单位转换变化信号
        emit conversionInfoChanged(m_currentImageGuid, m_lengthRatio, m_timeRatio, m_wavelengthRatio ,
                                   m_lengthUnit,m_timeUnit,m_wavelengthUnit,
                                   ui->xAxisUnitComboBox->currentIndex(), ui->yAxisUnitComboBox->currentIndex());
    }
}

void GraphicsViewArea::updateCalibrationValues()
{
    if (!m_imageItem || !m_xCalibrationLine || !m_yCalibrationLine || !m_isCalibrating) {
        return; // 如果没有图像、标定线或标定功能未激活，不更新显示
    }

    // 获取图像项在场景中的位置
    QPointF imagePos = m_imageItem->pos();

    // 获取X轴和Y轴标定线的位置
    qreal lineX = m_xCalibrationLine->line().x1();
    qreal lineY = m_yCalibrationLine->line().y1();

    // 计算标定线相对于图像起始点的位置
    qreal relX = lineX - imagePos.x();
    qreal relY = lineY - imagePos.y();

    // 获取X轴和Y轴的当前单位和转换比例
    CoordinateAxisItem::AxisUnit xUnit = m_axisItem->xAxisUnit();
    CoordinateAxisItem::AxisUnit yUnit = m_axisItem->yAxisUnit();
    
    double xRatio = 1.0;
    double yRatio = 1.0;
    
    // 根据单位类型选择相应的转换比例
    if (xUnit == CoordinateAxisItem::Length) {
        xRatio = m_lengthRatio;
    } else if (xUnit == CoordinateAxisItem::Time) {
        xRatio = m_timeRatio;
    } else if (xUnit == CoordinateAxisItem::Wavelength) {
        xRatio = m_wavelengthRatio;
    }
    
    if (yUnit == CoordinateAxisItem::Length) {
        yRatio = m_lengthRatio;
    } else if (yUnit == CoordinateAxisItem::Time) {
        yRatio = m_timeRatio;
    } else if (yUnit == CoordinateAxisItem::Wavelength) {
        yRatio = m_wavelengthRatio;
    }

    // 根据相对图像的偏移、当前单位转换比例和缩放比例计算显示值
    qreal displayX = relX * xRatio / m_scale;
    qreal displayY = relY * yRatio / m_scale;
    
    // 更新输入框显示
    ui->xCoordinateLineEdit->setText(QString::number(displayX, 'f', 2));
    ui->yCoordinateLineEdit->setText(QString::number(displayY, 'f', 2));
}

void GraphicsViewArea::updateMousePositionDisplay()
{
    if (!m_imageItem) {
        return;
    }

    // 获取X轴和Y轴的当前单位和转换比例
    CoordinateAxisItem::AxisUnit xUnit = m_axisItem->xAxisUnit();
    CoordinateAxisItem::AxisUnit yUnit = m_axisItem->yAxisUnit();
    
    double xRatio = 1.0;
    double yRatio = 1.0;
    QString xUnitStr = "px";
    QString yUnitStr = "px";
    
    // 根据单位类型选择相应的转换比例
    if (xUnit == CoordinateAxisItem::Length) {
        xRatio = m_lengthRatio;
        xUnitStr = m_lengthUnit;
    } else if (xUnit == CoordinateAxisItem::Time) {
        xRatio = m_timeRatio;
        xUnitStr = m_timeUnit;
    } else if (xUnit == CoordinateAxisItem::Wavelength) {
        xRatio = m_wavelengthRatio;
        xUnitStr = m_wavelengthUnit;
    }
    
    if (yUnit == CoordinateAxisItem::Length) {
        yRatio = m_lengthRatio;
        yUnitStr = m_lengthUnit;
    } else if (yUnit == CoordinateAxisItem::Time) {
        yRatio = m_timeRatio;
        yUnitStr = m_timeUnit;
    } else if (yUnit == CoordinateAxisItem::Wavelength) {
        yRatio = m_wavelengthRatio;
        yUnitStr = m_wavelengthUnit;
    }
    
    // 根据存储的像素位置、当前单位转换比例和缩放比例计算显示值
    qreal displayX = m_mouseRelX * xRatio / m_scale;
    qreal displayY = m_mouseRelY * yRatio / m_scale;
    
    // 更新位置显示，包含单位
    ui->label_MouseX->setText(QString::number(displayX, 'f', 2) + " " + xUnitStr);
    ui->label_MouseY->setText(QString::number(displayY, 'f', 2) + " " + yUnitStr);
}

void GraphicsViewArea::onYAxisUnitChanged(const QString &unit)
{
    if (m_axisItem) {
        // 将字符串转换为AxisUnit枚举类型
        CoordinateAxisItem::AxisUnit axisUnit = CoordinateAxisItem::Pixel;
        double ratio = 1.0;
        QString unitString = "px";

        if (unit == "像素") {
            axisUnit = CoordinateAxisItem::Pixel;
            ratio = 1.0;
            unitString = "px";
        } else if (unit == "长度") {
            axisUnit = CoordinateAxisItem::Length;
            ratio = m_lengthRatio;
            // 使用动态存储的长度单位
            unitString = m_lengthUnit;
        } else if (unit == "时间") {
            axisUnit = CoordinateAxisItem::Time;
            ratio = m_timeRatio;
            // 使用动态存储的时间单位
            unitString = m_timeUnit;
        } else if (unit == "波长") {
            axisUnit = CoordinateAxisItem::Wavelength;
            ratio = m_wavelengthRatio;
            // 使用动态存储的波长单位
            unitString = m_wavelengthUnit;
        }

        // 设置Y轴单位、转换比例和具体单位字符串
        m_axisItem->setYAxisProperties(axisUnit, unitString, ratio);

        // 更新鼠标位置显示
        updateMousePositionDisplay();

        // 如果标定功能激活，根据标定线相对图像的偏移更新显示值
        if (m_isCalibrating) {
            updateCalibrationValues();
        }
        // 发出单位转换变化信号
        emit conversionInfoChanged(m_currentImageGuid, m_lengthRatio, m_timeRatio, m_wavelengthRatio ,
                                   m_lengthUnit,m_timeUnit,m_wavelengthUnit,
                                   ui->xAxisUnitComboBox->currentIndex(), ui->yAxisUnitComboBox->currentIndex());
    }
}



void GraphicsViewArea::on_unitSettingsPushButton_clicked()
{
    // 创建并显示转换比例设置弹出框
    UnitConversionDialog dialog(this);

    // 设置当前转换比例和上次选择的单位
    dialog.setLengthRatio(m_lengthRatio);
    dialog.setTimeRatio(m_timeRatio);
    dialog.setWavelengthRatio(m_wavelengthRatio);
    
    // 设置上次选择的单位
    dialog.setLengthUnit(m_lengthUnit);
    dialog.setTimeUnit(m_timeUnit);
    dialog.setWavelengthUnit(m_wavelengthUnit);

    // 显示对话框并等待用户操作
    if (dialog.exec() == QDialog::Accepted) {
        // 获取用户设置的转换比例和单位
        double newLengthRatio = dialog.getLengthRatio();
        double newTimeRatio = dialog.getTimeRatio();
        double newWavelengthRatio = dialog.getWavelengthRatio();
        QString newLengthUnit = dialog.getLengthUnit();
        QString newTimeUnit = dialog.getTimeUnit();
        QString newWavelengthUnit = dialog.getWavelengthUnit();

        // 检查转换比例是否发生变化
        if (newLengthRatio != m_lengthRatio || newTimeRatio != m_timeRatio || newWavelengthRatio != m_wavelengthRatio||
                m_lengthUnit != newLengthUnit || m_timeUnit != newTimeUnit || m_wavelengthUnit != newWavelengthUnit) {
            // 更新转换比例
            m_lengthRatio = newLengthRatio;
            m_timeRatio = newTimeRatio;
            m_wavelengthRatio = newWavelengthRatio;

            // 保存用户选择的单位
            m_lengthUnit = newLengthUnit;
            m_timeUnit = newTimeUnit;
            m_wavelengthUnit = newWavelengthUnit;

            // 应用设置到X轴和Y轴
            onXAxisUnitChanged(ui->xAxisUnitComboBox->currentText());
            onYAxisUnitChanged(ui->yAxisUnitComboBox->currentText());

            // 更新鼠标位置显示
            updateMousePositionDisplay();
            
            // 如果标定功能激活，根据标定线相对图像的偏移更新显示值
            if (m_isCalibrating) {
                updateCalibrationValues();
            }

            // 发出单位转换变化信号
            emit conversionInfoChanged(m_currentImageGuid, m_lengthRatio, m_timeRatio, m_wavelengthRatio ,
                                       m_lengthUnit,m_timeUnit,m_wavelengthUnit,
                                       ui->xAxisUnitComboBox->currentIndex(), ui->yAxisUnitComboBox->currentIndex());
        }
        

        
        // 更新坐标轴的单位字符串
        if (m_axisItem) {
            if (ui->xAxisUnitComboBox->currentText() == "长度") {
                m_axisItem->setXAxisUnitString(newLengthUnit);
            } else if (ui->xAxisUnitComboBox->currentText() == "时间") {
                m_axisItem->setXAxisUnitString(newTimeUnit);
            } else if (ui->xAxisUnitComboBox->currentText() == "波长") {
                m_axisItem->setXAxisUnitString(newWavelengthUnit);
            }
            
            if (ui->yAxisUnitComboBox->currentText() == "长度") {
                m_axisItem->setYAxisUnitString(newLengthUnit);
            } else if (ui->yAxisUnitComboBox->currentText() == "时间") {
                m_axisItem->setYAxisUnitString(newTimeUnit);
            } else if (ui->yAxisUnitComboBox->currentText() == "波长") {
                m_axisItem->setYAxisUnitString(newWavelengthUnit);
            }
        }
    }
}


void GraphicsViewArea::on_movePushButton_clicked(bool checked)
{
    // 根据按钮的选中状态来启用或禁用拖动功能
    if (checked) {
        // 启用拖动功能
        ui->imagesDisplayGraphicsView->setDragMode(QGraphicsView::ScrollHandDrag);
    } else {
        // 禁用拖动功能
        ui->imagesDisplayGraphicsView->setDragMode(QGraphicsView::NoDrag);
    }
}

void GraphicsViewArea::on_revokePushButton_clicked()
{
    // 当用户点击撤销按钮时，如果有当前显示的图像，发出撤销请求信号
    if (!m_currentImageGuid.isEmpty()) {
        emit undoRequested(m_currentImageGuid);
    }
}

void GraphicsViewArea::on_repeatPushButton_clicked()
{
    // 当用户点击重做按钮时，如果有当前显示的图像，发出重做请求信号
    if (!m_currentImageGuid.isEmpty()) {
        emit redoRequested(m_currentImageGuid);
    }
}

